home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / sgi2fax / row.c < prev   
C/C++ Source or Header  |  1994-08-01  |  13KB  |  691 lines

  1. /*    $Header: /usr/people/sam/fax/sgi2fax/RCS/row.c,v 1.6 1994/02/28 14:23:14 sam Rel $
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. /*
  26.  *    row -
  27.  *        support for operations on image rows.
  28.  *
  29.  */
  30. #include "image.h"
  31. #include "lum.h"
  32.  
  33. int    _RILUM = _RED;
  34. int    _GILUM = _GREEN;
  35. int    _BILUM = _BLUE;
  36.  
  37. zerorow(sptr,n)
  38. short *sptr;
  39. int n;
  40. {
  41.     memset(sptr,0,n*sizeof(short));
  42. }
  43.  
  44. copyrow(s,d,n)
  45. short *s, *d;
  46. int n;
  47. {
  48.     memcpy(d,s,n*sizeof(short));
  49. }
  50.  
  51. setrow(sptr,val,n)
  52. short *sptr;
  53. int val, n;
  54. {
  55.     if(val==0)
  56.     zerorow(sptr,n);
  57.     else {
  58.     while(n>=8) {
  59.         sptr[0] = val;
  60.         sptr[1] = val;
  61.         sptr[2] = val;
  62.         sptr[3] = val;
  63.         sptr[4] = val;
  64.         sptr[5] = val;
  65.         sptr[6] = val;
  66.         sptr[7] = val;
  67.         sptr += 8;
  68.         n -= 8;
  69.     }
  70.     while(n--) 
  71.         *sptr++ = val;
  72.     }
  73. }
  74.  
  75. #define DOCLAMP(iptr,optr)    *(optr) = ((*(iptr)<0) ? 0 : (*(iptr)>255) ? 255 : *(iptr))
  76.  
  77. clamprow(iptr,optr,n)
  78. short *iptr, *optr;
  79. int n;
  80. {
  81.     short  val;
  82.  
  83.     while(n>=8) {
  84.     DOCLAMP(iptr+0,optr+0);
  85.     DOCLAMP(iptr+1,optr+1);
  86.     DOCLAMP(iptr+2,optr+2);
  87.     DOCLAMP(iptr+3,optr+3);
  88.     DOCLAMP(iptr+4,optr+4);
  89.     DOCLAMP(iptr+5,optr+5);
  90.     DOCLAMP(iptr+6,optr+6);
  91.     DOCLAMP(iptr+7,optr+7);
  92.     iptr += 8;
  93.     optr += 8;
  94.     n -= 8;
  95.     }
  96.     while(n--) {
  97.     DOCLAMP(iptr,optr);
  98.     iptr++;
  99.     optr++;
  100.     }
  101. }
  102.  
  103. accrow(iptr,sptr,w,n)
  104. short *iptr;
  105. short *sptr;
  106. int w, n;
  107. {
  108.     if(w == 1) {
  109.     addsrow(iptr,sptr,n);
  110.     } else if(w == -1) {
  111.     subsrow(iptr,sptr,n);
  112.     } else {
  113.     while(n>=8) {
  114.         iptr[0] += w*sptr[0];
  115.         iptr[1] += w*sptr[1];
  116.         iptr[2] += w*sptr[2];
  117.         iptr[3] += w*sptr[3];
  118.         iptr[4] += w*sptr[4];
  119.         iptr[5] += w*sptr[5];
  120.         iptr[6] += w*sptr[6];
  121.         iptr[7] += w*sptr[7];
  122.         iptr += 8;
  123.         sptr += 8;
  124.         n -= 8;
  125.     }
  126.     while(n--) 
  127.         *iptr++ += (w * *sptr++);
  128.     }
  129. }
  130.  
  131. divrow(iptr,optr,tot,n)
  132. short *iptr;
  133. short *optr;
  134. int tot, n;
  135. {
  136.     if(iptr == optr) {
  137.     while(n>=8) {
  138.         optr[0] = optr[0]/tot;
  139.         optr[1] = optr[1]/tot;
  140.         optr[2] = optr[2]/tot;
  141.         optr[3] = optr[3]/tot;
  142.         optr[4] = optr[4]/tot;
  143.         optr[5] = optr[5]/tot;
  144.         optr[6] = optr[6]/tot;
  145.         optr[7] = optr[7]/tot;
  146.         optr += 8;
  147.         n -= 8;
  148.     }
  149.     while(n--) {
  150.         *optr = (*optr)/tot;
  151.         optr++;
  152.     }
  153.     } else {
  154.     while(n>=8) {
  155.         optr[0] = iptr[0]/tot;
  156.         optr[1] = iptr[1]/tot;
  157.         optr[2] = iptr[2]/tot;
  158.         optr[3] = iptr[3]/tot;
  159.         optr[4] = iptr[4]/tot;
  160.         optr[5] = iptr[5]/tot;
  161.         optr[6] = iptr[6]/tot;
  162.         optr[7] = iptr[7]/tot;
  163.         optr += 8;
  164.         iptr += 8;
  165.         n -= 8;
  166.     }
  167.     while(n--) 
  168.         *optr++ = (*iptr++)/tot;
  169.     }
  170. }
  171.  
  172. #define DOTOBW(optr,rptr,gptr,bptr)    *(optr) = ILUM(*(rptr),*(gptr),*(bptr))
  173.  
  174. rgbrowtobw(rbuf,gbuf,bbuf,obuf,n)
  175. unsigned short *rbuf, *gbuf, *bbuf, *obuf;
  176. int n;
  177. {
  178.     while(n>=8) {
  179.     DOTOBW(obuf+0,rbuf+0,gbuf+0,bbuf+0);
  180.     DOTOBW(obuf+1,rbuf+1,gbuf+1,bbuf+1);
  181.     DOTOBW(obuf+2,rbuf+2,gbuf+2,bbuf+2);
  182.     DOTOBW(obuf+3,rbuf+3,gbuf+3,bbuf+3);
  183.     DOTOBW(obuf+4,rbuf+4,gbuf+4,bbuf+4);
  184.     DOTOBW(obuf+5,rbuf+5,gbuf+5,bbuf+5);
  185.     DOTOBW(obuf+6,rbuf+6,gbuf+6,bbuf+6);
  186.     DOTOBW(obuf+7,rbuf+7,gbuf+7,bbuf+7);
  187.     rbuf += 8;
  188.     gbuf += 8;
  189.     bbuf += 8;
  190.     obuf += 8;
  191.     n -= 8;
  192.     } 
  193.     while(n--) {
  194.     DOTOBW(obuf,rbuf,gbuf,bbuf);
  195.     rbuf++;
  196.     gbuf++;
  197.     bbuf++;
  198.     obuf++;
  199.     }
  200. }
  201.  
  202. /*
  203.  *    addsrow -
  204.  *        Add two rows together
  205.  *
  206.  */
  207. addsrow(dptr,sptr,n)
  208. short *dptr, *sptr;
  209. int n;
  210. {
  211.     while(n>=8) {
  212.     dptr[0] += sptr[0];
  213.     dptr[1] += sptr[1];
  214.     dptr[2] += sptr[2];
  215.     dptr[3] += sptr[3];
  216.     dptr[4] += sptr[4];
  217.     dptr[5] += sptr[5];
  218.     dptr[6] += sptr[6];
  219.     dptr[7] += sptr[7];
  220.     dptr += 8;
  221.     sptr += 8;
  222.     n -= 8;
  223.     }
  224.     while(n--) 
  225.     *dptr++ += *sptr++;
  226. }
  227.  
  228. /*
  229.  *    subsrow -
  230.  *        Subtract two rows
  231.  *
  232.  */
  233. subsrow(dptr,sptr,n)
  234. short *dptr, *sptr;
  235. int n;
  236. {
  237.     while(n>=8) {
  238.     dptr[0] -= sptr[0];
  239.     dptr[1] -= sptr[1];
  240.     dptr[2] -= sptr[2];
  241.     dptr[3] -= sptr[3];
  242.     dptr[4] -= sptr[4];
  243.     dptr[5] -= sptr[5];
  244.     dptr[6] -= sptr[6];
  245.     dptr[7] -= sptr[7];
  246.     dptr += 8;
  247.     sptr += 8;
  248.     n -= 8;
  249.     }
  250.     while(n--) 
  251.     *dptr++ -= *sptr++;
  252. }
  253.  
  254. bitstorow(bits,sbuf,n)
  255. unsigned char *bits;
  256. short *sbuf;
  257. int n;
  258. {
  259.     int i, val, nbytes;
  260.  
  261.     nbytes = ((n-1)/8)+1;
  262.     for(i = 0; i<nbytes; i++ ) {
  263.     val = *bits++;
  264.     if(val&0x80)
  265.         sbuf[0] = 0;
  266.     else
  267.         sbuf[0] = 255;
  268.     if(val&0x40)
  269.         sbuf[1] = 0;
  270.     else
  271.         sbuf[1] = 255;
  272.     if(val&0x20)
  273.         sbuf[2] = 0;
  274.     else
  275.         sbuf[2] = 255;
  276.     if(val&0x10)
  277.         sbuf[3] = 0;
  278.     else
  279.         sbuf[3] = 255;
  280.     if(val&0x08)
  281.         sbuf[4] = 0;
  282.     else
  283.         sbuf[4] = 255;
  284.     if(val&0x04)
  285.         sbuf[5] = 0;
  286.     else
  287.         sbuf[5] = 255;
  288.     if(val&0x02)
  289.         sbuf[6] = 0;
  290.     else
  291.         sbuf[6] = 255;
  292.     if(val&0x01)
  293.         sbuf[7] = 0;
  294.     else
  295.         sbuf[7] = 255;
  296.     sbuf += 8;
  297.     }
  298. }
  299.  
  300. rowtobits(sbuf,bits,n)
  301. short *sbuf;
  302. unsigned char *bits;
  303. int n;
  304. {
  305.     int i, val, nbytes, thresh;
  306.  
  307.     nbytes = ((n-1)/8)+1;
  308.     thresh = 128;
  309.     for(i = 0; i<nbytes; i++) {
  310.     val = 0;
  311.     if(sbuf[0]<thresh)
  312.         val |= 0x80;
  313.     if(sbuf[1]<thresh)
  314.         val |= 0x40;
  315.     if(sbuf[2]<thresh)
  316.         val |= 0x20;
  317.     if(sbuf[3]<thresh)
  318.         val |= 0x10;
  319.     if(sbuf[4]<thresh)
  320.         val |= 0x08;
  321.     if(sbuf[5]<thresh)
  322.         val |= 0x04;
  323.     if(sbuf[6]<thresh)
  324.         val |= 0x02;
  325.     if(sbuf[7]<thresh)
  326.         val |= 0x01;
  327.     sbuf += 8;
  328.     *bits++ = val;
  329.     }
  330. }
  331.  
  332. /* 
  333.  *    bit reverse a stream of bytes
  334.  *
  335.  */
  336. bitrevbytes(buf,n)
  337. unsigned char *buf;
  338. int n;
  339. {
  340.     int i, x, br;
  341.     static unsigned char *bitrev;
  342.  
  343.     if(!bitrev) {
  344.     bitrev = (unsigned char *)malloc(256);
  345.     for(i=0; i<256; i++) {
  346.         br = 0;
  347.         for(x=0; x<8; x++) {
  348.         br = br<<1;
  349.         if(i&(1<<x))
  350.             br |= 1;
  351.         }
  352.         bitrev[i] = br;
  353.     }
  354.     }
  355.     while(n>=8) {
  356.     buf[0] = bitrev[buf[0]];
  357.     buf[1] = bitrev[buf[1]];
  358.     buf[2] = bitrev[buf[2]];
  359.     buf[3] = bitrev[buf[3]];
  360.     buf[4] = bitrev[buf[4]];
  361.     buf[5] = bitrev[buf[5]];
  362.     buf[6] = bitrev[buf[6]];
  363.     buf[7] = bitrev[buf[7]];
  364.     buf += 8;
  365.     n -= 8;
  366.     }
  367.     while(n--) {
  368.     buf[0] = bitrev[buf[0]];
  369.     *buf++;
  370.     }
  371. }
  372.  
  373. /* 
  374.  *    flip a row of shorts
  375.  *
  376.  */
  377. flipsrow(sptr,n) 
  378. register short *sptr;
  379. register int n;
  380. {
  381.     register short temp, *p1, *p2;
  382.  
  383.     p1 = sptr;
  384.     p2 = sptr+n-1;
  385.     n = n/2;
  386.     while(n--) {
  387.     temp = *p1;
  388.     *p1++ = *p2;
  389.     *p2-- = temp;
  390.     }
  391. }
  392.  
  393. /*     cpack -
  394.  *        Convert from and to cpack format.
  395.  *    
  396.  */
  397. bwtocpack(b,l,n)
  398. register unsigned short *b;
  399. register unsigned long *l;
  400. register int n;
  401. {
  402.     while(n>=8) {
  403.     l[0] = 0x00010101*b[0];
  404.     l[1] = 0x00010101*b[1];
  405.     l[2] = 0x00010101*b[2];
  406.     l[3] = 0x00010101*b[3];
  407.     l[4] = 0x00010101*b[4];
  408.     l[5] = 0x00010101*b[5];
  409.     l[6] = 0x00010101*b[6];
  410.     l[7] = 0x00010101*b[7];
  411.     l += 8;
  412.     b += 8;
  413.     n -= 8;
  414.     }
  415.     while(n--) 
  416.     *l++ = 0x00010101*(*b++);
  417. }
  418.  
  419. rgbtocpack(r,g,b,l,n)
  420. register unsigned short *r, *g, *b;
  421. register unsigned long *l;
  422. register int n;
  423. {
  424.     while(n>=8) {
  425.     l[0] = r[0] | (g[0]<<8) | (b[0]<<16);
  426.     l[1] = r[1] | (g[1]<<8) | (b[1]<<16);
  427.     l[2] = r[2] | (g[2]<<8) | (b[2]<<16);
  428.     l[3] = r[3] | (g[3]<<8) | (b[3]<<16);
  429.     l[4] = r[4] | (g[4]<<8) | (b[4]<<16);
  430.     l[5] = r[5] | (g[5]<<8) | (b[5]<<16);
  431.     l[6] = r[6] | (g[6]<<8) | (b[6]<<16);
  432.     l[7] = r[7] | (g[7]<<8) | (b[7]<<16);
  433.     l += 8;
  434.     r += 8;
  435.     g += 8;
  436.     b += 8;
  437.     n -= 8;
  438.     }
  439.     while(n--) 
  440.         *l++ = *r++ | ((*g++)<<8) | ((*b++)<<16);
  441. }
  442.  
  443. rgbatocpack(r,g,b,a,l,n)
  444. register unsigned short *r, *g, *b, *a;
  445. register unsigned long *l;
  446. register int n;
  447. {
  448.     while(n>=8) {
  449.     l[0] = r[0] | (g[0]<<8) | (b[0]<<16) | (a[0]<<24);
  450.     l[1] = r[1] | (g[1]<<8) | (b[1]<<16) | (a[1]<<24);
  451.     l[2] = r[2] | (g[2]<<8) | (b[2]<<16) | (a[2]<<24);
  452.     l[3] = r[3] | (g[3]<<8) | (b[3]<<16) | (a[3]<<24);
  453.     l[4] = r[4] | (g[4]<<8) | (b[4]<<16) | (a[4]<<24);
  454.     l[5] = r[5] | (g[5]<<8) | (b[5]<<16) | (a[5]<<24);
  455.     l[6] = r[6] | (g[6]<<8) | (b[6]<<16) | (a[6]<<24);
  456.     l[7] = r[7] | (g[7]<<8) | (b[7]<<16) | (a[7]<<24);
  457.     l += 8;
  458.     r += 8;
  459.     g += 8;
  460.     b += 8;
  461.     a += 8;
  462.     n -= 8;
  463.     }
  464.     while(n--) 
  465.         *l++ = *r++ | ((*g++)<<8) | ((*b++)<<16) | ((*a++)<<24);
  466. }
  467.  
  468. #define CPACKTORGB(l,r,g,b)            \
  469.     val = (l);                \
  470.     (r) = (val>>0) & 0xff;            \
  471.     (g) = (val>>8) & 0xff;            \
  472.     (b) = (val>>16) & 0xff;            
  473.  
  474. cpacktorgb(l,r,g,b,n)
  475. register unsigned long *l;
  476. register unsigned short *r, *g, *b;
  477. register int n;
  478. {
  479.     unsigned long val;
  480.  
  481.     while(n>=8) {
  482.     CPACKTORGB(l[0],r[0],g[0],b[0]);
  483.     CPACKTORGB(l[1],r[1],g[1],b[1]);
  484.     CPACKTORGB(l[2],r[2],g[2],b[2]);
  485.     CPACKTORGB(l[3],r[3],g[3],b[3]);
  486.     CPACKTORGB(l[4],r[4],g[4],b[4]);
  487.     CPACKTORGB(l[5],r[5],g[5],b[5]);
  488.     CPACKTORGB(l[6],r[6],g[6],b[6]);
  489.     CPACKTORGB(l[7],r[7],g[7],b[7]);
  490.     l += 8;
  491.     r += 8;
  492.     g += 8;
  493.     b += 8;
  494.     n -= 8;
  495.     }
  496.     while(n--) {
  497.     CPACKTORGB(l[0],r[0],g[0],b[0]);
  498.     l++;
  499.     r++;
  500.     g++;
  501.     b++;
  502.     }
  503. }
  504.  
  505. #define CPACKTORGBA(l,r,g,b,a)            \
  506.     val = (l);                \
  507.     (r) = (val>>0) & 0xff;            \
  508.     (g) = (val>>8) & 0xff;            \
  509.     (b) = (val>>16) & 0xff;            \
  510.     (a) = (val>>24) & 0xff;            
  511.  
  512. cpacktorgba(l,r,g,b,a,n)
  513. register unsigned long *l;
  514. register unsigned short *r, *g, *b, *a;
  515. register int n;
  516. {
  517.     unsigned long val;
  518.  
  519.     while(n>=8) {
  520.     CPACKTORGBA(l[0],r[0],g[0],b[0],a[0]);
  521.     CPACKTORGBA(l[1],r[1],g[1],b[1],a[1]);
  522.     CPACKTORGBA(l[2],r[2],g[2],b[2],a[2]);
  523.     CPACKTORGBA(l[3],r[3],g[3],b[3],a[3]);
  524.     CPACKTORGBA(l[4],r[4],g[4],b[4],a[4]);
  525.     CPACKTORGBA(l[5],r[5],g[5],b[5],a[5]);
  526.     CPACKTORGBA(l[6],r[6],g[6],b[6],a[6]);
  527.     CPACKTORGBA(l[7],r[7],g[7],b[7],a[7]);
  528.     l += 8;
  529.     r += 8;
  530.     g += 8;
  531.     b += 8;
  532.     a += 8;
  533.     n -= 8;
  534.     }
  535.     while(n--) {
  536.     CPACKTORGBA(l[0],r[0],g[0],b[0],a[0]);
  537.     l++;
  538.     r++;
  539.     g++;
  540.     b++;
  541.     a++;
  542.     }
  543. }
  544.  
  545. /*
  546.  *    normrow -
  547.  *        Normalize a row of image data
  548.  *
  549.  */
  550. normrow(image,buf)
  551. IMAGE *image;
  552. short *buf;
  553. {
  554.     int n, max;
  555.  
  556.     n = image->xsize;
  557.     max = image->max;
  558.     if(max == 255 || max == 0)
  559.     return;
  560.     while(n>=8) {
  561.     buf[0] = (buf[0]*255)/max;
  562.     buf[1] = (buf[1]*255)/max;
  563.     buf[2] = (buf[2]*255)/max;
  564.     buf[3] = (buf[3]*255)/max;
  565.     buf[4] = (buf[4]*255)/max;
  566.     buf[5] = (buf[5]*255)/max;
  567.     buf[6] = (buf[6]*255)/max;
  568.     buf[7] = (buf[7]*255)/max;
  569.     buf += 8;
  570.     n -= 8;
  571.     }
  572.     while(n--) {
  573.     *buf = (*buf*255)/max;
  574.     buf++;
  575.     }
  576. }
  577.  
  578. static short *rbuf, *gbuf, *bbuf;
  579. static int malloclen = 0;
  580.  
  581. getbwrow(image,buf,y)
  582. IMAGE *image;
  583. char *buf;
  584. int y;
  585. {
  586.     if(malloclen!=image->xsize) {
  587.     if(malloclen) {
  588.         free(rbuf);
  589.         free(gbuf);
  590.         free(bbuf);
  591.     }
  592.     rbuf = (short *)malloc(image->xsize*sizeof(short));
  593.     gbuf = (short *)malloc(image->xsize*sizeof(short));
  594.     bbuf = (short *)malloc(image->xsize*sizeof(short));
  595.     malloclen=image->xsize;;
  596.     }
  597.     if(image->zsize<3) {
  598.     getrow(image,buf,y,0);
  599.     } else {
  600.     getrow(image,rbuf,y,0);
  601.     getrow(image,gbuf,y,1);
  602.     getrow(image,bbuf,y,2);
  603.     rgbrowtobw(rbuf,gbuf,bbuf,buf,image->xsize);
  604.     }
  605. }
  606.  
  607. putfliprow(image,buf,y,z,flipcode)
  608. IMAGE *image;
  609. short *buf;
  610. int y, z;
  611. int flipcode;
  612. {
  613.     if(flipcode&1)
  614.     flipsrow(buf,image->xsize);
  615.     if(flipcode&2)
  616.     putrow(image,buf,(image->ysize-1)-y,z);
  617.     else
  618.     putrow(image,buf,y,z);
  619. }
  620.  
  621. getfliprow(image,buf,y,z,flipcode)
  622. IMAGE *image;
  623. short *buf;
  624. int y, z, flipcode;
  625. {
  626.     if(flipcode&2)
  627.     getrow(image,buf,(image->ysize-1)-y,z);
  628.     else
  629.     getrow(image,buf,y,z);
  630.     if(flipcode&1)
  631.     flipsrow(buf,image->xsize);
  632. }
  633.  
  634. /* 
  635.  *    dithering stuff follows
  636.  *
  637.  */
  638. #define MATSIZE88
  639.  
  640. #define XSIZE    8
  641. #define YSIZE    8
  642.  
  643. static short dithmat[YSIZE][XSIZE] = {        /* 8x8 Limb */
  644.     0,    8,    36,    44,    2,    10,    38,    46,
  645.     16,    24,    52,    60,    18,    26,    54,    62,
  646.     32,    40,     4,    12,    34,    42,    6,    14,
  647.     48,    56,    20,    28,    50,    58,    22,    30,
  648.     3,    11,    39,    47,    1,    9,    37,    45,
  649.     19,    27,    55,    63,    17,    25,    53,    61,
  650.     35,    43,    7,    15,    33,    41,    5,    13,
  651.     51,    59,    23,    31,    49,    57,    21,    29,
  652. };
  653.  
  654. #ifdef NOTDEF
  655. static short dithmat[YSIZE][XSIZE] = {        /* halftone dots */
  656.     3,    17,    55,     63,    61,     47,    9,    1,
  657.     15,     29,    39,    51,    49,    35,    25,    13,
  658.     40,    32,    26,    20,    22,    30,    36,    42,
  659.     56,    44,    10,    4,    6,    18,    52,    58,
  660.     60,    46,    8,    0,    2,    16,    54,    62,
  661.     48,    34,    24,    12,    14,    28,    38,    50,
  662.     23,    31,    37,    43,    41,    33,    27,    21,
  663.     7,    19,    53,    59,    57,    45,    11,    5,
  664. };
  665.  
  666. #define TOTAL        (XSIZE*YSIZE)
  667.  
  668. ditherrow(buf,y,n)
  669. short *buf;
  670. int y, n;
  671. {
  672.     int r, val;
  673.     int rshades, rmaxbits;
  674.     short *rdith, *gdith, *bdith;
  675.  
  676.     rdith = &dithmat[y%YSIZE][0];
  677.     rshades = TOTAL+1;
  678.     rmaxbits = ((rshades-1)/TOTAL);
  679.     while(n--) {
  680.     r = *buf;
  681.     val = (rshades*r)/255;
  682.     if(val>=TOTAL) 
  683.         *buf++ = 255;
  684.     else if(val>rdith[n%XSIZE])
  685.         *buf++ = 255;
  686.     else
  687.         *buf++ = 0;
  688.     }
  689. }
  690. #endif
  691.